package com.gmcloud.common.swagger.config;

import com.gmcloud.common.swagger.support.SwaggerProperties;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.OAuthFlow;
import io.swagger.v3.oas.models.security.OAuthFlows;
import io.swagger.v3.oas.models.security.Scopes;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpHeaders;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author zl.sir
 * @version 1.0
 * @since 2022/8/17 0:05
 */
@ConditionalOnProperty(name = "swagger.enabled",matchIfMissing = true)
//@ConditionalOnMissingClass如果没有后面的类，才自动配置
@ConditionalOnMissingClass("org.springframework.cloud.gateway.config.GatewayAutoConfiguration")
public class SwaggerAutoConfiguration {

    private final SwaggerProperties swaggerProperties;

    private final ServiceInstance serviceInstance;

    public SwaggerAutoConfiguration(SwaggerProperties swaggerProperties, ServiceInstance serviceInstance) {
        this.swaggerProperties = swaggerProperties;
        this.serviceInstance = serviceInstance;
    }

    /**
     * swagger配置信息
     * @return
     */
    @Bean
    public OpenAPI springOpenAPI() {
        OpenAPI openAPI = new OpenAPI().info(new Info().title(swaggerProperties.getTitle())
                .license(swaggerProperties.getLicense()).version(swaggerProperties.getVersion()));
        // oauth2.0 password
        openAPI.schemaRequirement(HttpHeaders.AUTHORIZATION, this.securityScheme());
        // servers
        List<Server> serverList = new ArrayList<>();
        if (Objects.nonNull(swaggerProperties.getServices())){
            String path = swaggerProperties.getServices().get(serviceInstance.getServiceId());
            serverList.add(new Server().url(swaggerProperties.getGateway() + "/" + path));
        }
        openAPI.servers(serverList);
        return openAPI;
    }

    private SecurityScheme securityScheme() {
        OAuthFlow clientCredential = new OAuthFlow();
        clientCredential.setTokenUrl(swaggerProperties.getTokenUrl());
        clientCredential.setScopes(new Scopes().addString(swaggerProperties.getScope(), swaggerProperties.getScope()));
        OAuthFlows oauthFlows = new OAuthFlows();
        oauthFlows.password(clientCredential);
        SecurityScheme securityScheme = new SecurityScheme();
        securityScheme.setType(SecurityScheme.Type.OAUTH2);
        securityScheme.setFlows(oauthFlows);
        return securityScheme;
    }
}
